﻿using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Threading;
using System.Timers;

namespace SpriteEditor
{
    public partial class frmMain
    {
        //Common updating
        public void refreshFrameGrid()
        {
            dataGridView_Frames.DataSource = null;
            if (spr.lst_Frames != null && spr.lst_Frames.Count > 0)
                dataGridView_Frames.DataSource = spr.lst_Frames;
            dataGridView_Frames.Refresh();
        }

        public void refreshModuleOfFramesGrid()
        {
            dataGridView_ModulesOfFrame.DataSource = null;
            if (dataGridView_Frames.CurrentRow != null)
            {
                int curFrame = dataGridView_Frames.CurrentRow.Index;
                if (spr.lst_Frames[curFrame].lst_ModulesOfFrame != null
                    && spr.lst_Frames[curFrame].lst_ModulesOfFrame.Count > 0)
                    dataGridView_ModulesOfFrame.DataSource = spr.lst_Frames[curFrame].lst_ModulesOfFrame;
            }
            dataGridView_ModulesOfFrame.Refresh();
        }

        public void setCurrentFrameOnGrid(int curIndex)
        {
            if (dataGridView_Frames.Rows.Count > curIndex)
            {
                dataGridView_Frames.ClearSelection();
                dataGridView_Frames.CurrentCell = dataGridView_Frames.Rows[curIndex].Cells[0];
                dataGridView_Frames.Rows[curIndex].Selected = true;
                updateCurFrameSelection();
                updateCurMOFramesSelection();
            }
        }

        public void setCurrentModuleOfFramesOnGrid(int curIndex)
        {
            if (dataGridView_Frames.CurrentRow != null)
            {
                //int curFrame = dataGridView_Frames.CurrentRow.Index;
                if (dataGridView_ModulesOfFrame.Rows.Count > curIndex)
                {
                    dataGridView_ModulesOfFrame.ClearSelection();
                    dataGridView_ModulesOfFrame.CurrentCell = dataGridView_ModulesOfFrame.Rows[curIndex].Cells[0];
                    dataGridView_ModulesOfFrame.Rows[curIndex].Selected = true;
                    updateCurMOFramesSelection();
                }
            }
        }

        private void updateCurFrameSelection()
        {
            if (dataGridView_Frames.DataSource != null && dataGridView_Frames.CurrentRow != null
                    && spr != null && spr.lst_Frames != null
                    && dataGridView_Frames.CurrentRow.Index < spr.lst_Frames.Count)
            {
                dataGridView_ModulesOfFrame.DataSource = null;
                if (spr.lst_Frames[dataGridView_Frames.CurrentRow.Index].lst_ModulesOfFrame != null
                    && spr.lst_Frames[dataGridView_Frames.CurrentRow.Index].lst_ModulesOfFrame.Count > 0)
                    dataGridView_ModulesOfFrame.DataSource = spr.lst_Frames[dataGridView_Frames.CurrentRow.Index].lst_ModulesOfFrame;
            }
        }

        private void updateCurMOFramesSelection()
        {
            if (dataGridView_Frames != null && dataGridView_Frames.DataSource != null
                && dataGridView_Frames.CurrentRow != null
                && dataGridView_ModulesOfFrame != null && dataGridView_ModulesOfFrame.DataSource != null
                && dataGridView_ModulesOfFrame.CurrentRow != null
                && spr.lst_Frames != null
                && spr.lst_Frames[dataGridView_Frames.CurrentRow.Index].lst_ModulesOfFrame != null)
            {
                int cur_FrameIndex = dataGridView_Frames.CurrentRow.Index;

                int cur_ModuleOfFrameIndex = dataGridView_ModulesOfFrame.CurrentRow.Index;

                int cur_ModuleIndex = -1;

                if (cur_ModuleOfFrameIndex >= 0 && spr.lst_Frames[cur_FrameIndex].lst_ModulesOfFrame.Count > 0 && cur_ModuleOfFrameIndex < spr.lst_Frames[cur_FrameIndex].lst_ModulesOfFrame.Count)
                {
                    cur_ModuleIndex = spr.getModuleIndexFromID(spr.lst_Frames[cur_FrameIndex].lst_ModulesOfFrame[cur_ModuleOfFrameIndex].ID);
                }
                else
                {
                    cur_ModuleIndex = -1;
                }

                if (cur_ModuleIndex >= 0)
                {
                    if (CurSel_Frame == null)
                        CurSel_Frame = new FrameSelection();
                    CurSel_Frame.CurrentFrameIndex = cur_FrameIndex;
                    CurSel_Frame.CurrentModuleOfFrameIndex = cur_ModuleOfFrameIndex;
                    CurSel_Frame.CurrentModuleIndex = cur_ModuleIndex;
                    CurSel_Frame.P1 = new Point(spr.lst_Frames[cur_FrameIndex].lst_ModulesOfFrame[cur_ModuleOfFrameIndex].OX,
                                                spr.lst_Frames[cur_FrameIndex].lst_ModulesOfFrame[cur_ModuleOfFrameIndex].OY);
                    CurSel_Frame.P2 = new Point(CurSel_Frame.P1.X + spr.lst_Modules[cur_ModuleIndex].W,
                                                CurSel_Frame.P1.Y + spr.lst_Modules[cur_ModuleIndex].H);
                }
                else
                {
                    CurSel_Frame = null;
                }
                DrawPanelFrame();
            }
            else
            {
                CurSel_Frame = null;
            }
        }

        public void updateMOFramesGridFromCurSel_Frame()
        {
            bFrameUpdateSelection = false;
            if (CurSel_Frame != null && spr.lst_Frames != null
                && spr.lst_Frames.Count > CurSel_Frame.CurrentFrameIndex
                && spr.lst_Frames[CurSel_Frame.CurrentFrameIndex].lst_ModulesOfFrame != null)
            {
                dataGridView_ModulesOfFrame.CurrentCell = dataGridView_ModulesOfFrame.Rows[CurSel_Frame.CurrentModuleOfFrameIndex].Cells[0];
                dataGridView_ModulesOfFrame.Rows[CurSel_Frame.CurrentModuleOfFrameIndex].Selected = true;
            }
            dataGridView_ModulesOfFrame.Refresh();
        }

        //Add frame button click
        public void addNewFrame()
        {
            if (spr != null && spr.spr_image != null && spr.lst_Modules != null)
            {
                spr.newFrame();

                refreshFrameGrid();
                setCurrentFrameOnGrid(dataGridView_Frames.Rows.Count - 1);
                DrawPanelFrame();
            }
        }

        //Delete Frame button click
        public void deleteFrame()
        {
            if (dataGridView_Frames.DataSource != null
                && dataGridView_Frames.CurrentRow != null
                && spr != null && spr.lst_Frames != null
                && dataGridView_Frames.Rows.Count > 0
                )
            {
                spr.removeFrameAtIndex(dataGridView_Frames.CurrentRow.Index);

                refreshFrameGrid();
                DrawPanelFrame();
            }
        }

        //Clone Frame button click
        public void cloneFrame()
        {
            if (spr != null && spr.lst_Frames != null
                && dataGridView_Frames.DataSource != null
                && dataGridView_Frames.CurrentRow != null
                && dataGridView_Frames.Rows.Count > 0)
            {
                int currentIdex = dataGridView_Frames.CurrentRow.Index;
                spr.cloneFrameAtIndex(currentIdex);

                refreshFrameGrid();
                setCurrentFrameOnGrid(currentIdex + 1);
                DrawPanelFrame();
            }
        }

        //Up Frame button click
        public void upFrame()
        {
            if (spr != null && spr.lst_Frames != null && spr.lst_Frames.Count >= 2
                && dataGridView_Frames.DataSource != null
                && dataGridView_Frames.CurrentRow != null
                && dataGridView_Frames.Rows.Count >= 2)
            {
                int currentRow = dataGridView_Frames.CurrentRow.Index;
                if (currentRow > 0)
                {
                    spr.upFrameAtIndex(currentRow);

                    refreshFrameGrid();
                    setCurrentFrameOnGrid(currentRow - 1);
                    DrawPanelFrame();
                }
            }
        }

        //Down Frame button click
        public void downFrame()
        {
            if (spr != null && spr.lst_Frames != null && spr.lst_Frames.Count >= 2
                && dataGridView_Frames.DataSource != null
                && dataGridView_Frames.CurrentRow != null
                && dataGridView_Frames.Rows.Count >= 2)
            {
                int currentRow = dataGridView_Frames.CurrentRow.Index;
                if (currentRow < dataGridView_Frames.Rows.Count - 1)
                {
                    spr.downFrameAtIndex(currentRow);

                    refreshFrameGrid();
                    setCurrentFrameOnGrid(currentRow + 1);
                    DrawPanelFrame();
                }
            }
        }

        //Add Module Of Frames button click
        public void newModuleOfFrame()
        {
            if (spr != null && spr.spr_image != null && spr.lst_Modules != null
                && dataGridView_Frames.CurrentRow != null)
            {
                int currentFrame = dataGridView_Frames.CurrentRow.Index;

                spr.newModuleOfFrames(currentFrame, curModuleIndexInFrameFlow);

                refreshModuleOfFramesGrid();
                setCurrentModuleOfFramesOnGrid(dataGridView_ModulesOfFrame.Rows.Count - 1);
                DrawPanelFrame();
            }
        }

        //Delete Module Of Frames button click
        public void deleteModuleOfFrame()
        {
            if (dataGridView_Frames.DataSource != null && dataGridView_Frames.CurrentRow != null
                && dataGridView_Frames.Rows.Count > 0
                && dataGridView_ModulesOfFrame.DataSource != null && dataGridView_ModulesOfFrame.CurrentRow != null
                && dataGridView_ModulesOfFrame.Rows.Count > 0
                && spr != null && spr.lst_Frames != null
                && spr.lst_Frames[dataGridView_Frames.CurrentRow.Index].lst_ModulesOfFrame != null
                && spr.lst_Frames[dataGridView_Frames.CurrentRow.Index].lst_ModulesOfFrame.Count > 0)
            {
                int crt_FrameIndex = dataGridView_Frames.CurrentRow.Index;
                int crt_MOFIndex = dataGridView_ModulesOfFrame.CurrentRow.Index;

                spr.deleteModuleOfFrames(crt_FrameIndex, crt_MOFIndex); 

                refreshModuleOfFramesGrid();
                DrawPanelFrame();
            }
        }

        //Clone Module Of Frames button click
        public void cloneModuleOfFrame()
        {
            if (spr != null && spr.lst_Frames != null && spr.lst_Frames.Count > 0
                && dataGridView_Frames.CurrentRow != null
                && dataGridView_Frames.Rows.Count > 0)
            {
                int crt_FrameIndex = dataGridView_Frames.CurrentRow.Index;
                if (spr.lst_Frames[crt_FrameIndex].lst_ModulesOfFrame != null
                    && spr.lst_Frames[crt_FrameIndex].lst_ModulesOfFrame.Count > 0
                    && dataGridView_ModulesOfFrame.CurrentRow != null
                    && dataGridView_ModulesOfFrame.Rows.Count > 0)
                {
                    int crt_MOFIndex = dataGridView_ModulesOfFrame.CurrentRow.Index;

                    spr.cloneModuleOfFrames(crt_FrameIndex, crt_MOFIndex);


                    refreshModuleOfFramesGrid();
                    setCurrentModuleOfFramesOnGrid(crt_MOFIndex + 1);
                    DrawPanelFrame();
                }
            }
        }

        //Up Module Of Frames button click
        public void upModuleOfFrame()
        {
            if (spr != null && spr.lst_Frames != null && spr.lst_Frames.Count > 0
                && dataGridView_Frames.CurrentRow != null
                && dataGridView_Frames.Rows.Count > 0)
            {
                int crt_FrameIndex = dataGridView_Frames.CurrentRow.Index;
                if (spr.lst_Frames[crt_FrameIndex].lst_ModulesOfFrame != null
                    && spr.lst_Frames[crt_FrameIndex].lst_ModulesOfFrame.Count >= 2
                    && dataGridView_ModulesOfFrame.CurrentRow != null
                    && dataGridView_ModulesOfFrame.Rows.Count >= 2)
                {
                    int crt_MOFrames = dataGridView_ModulesOfFrame.CurrentRow.Index;
                    if (crt_MOFrames > 0)
                    {
                        spr.upModuleOfFramesAtIndex(crt_FrameIndex, crt_MOFrames);

                        refreshModuleOfFramesGrid();
                        setCurrentModuleOfFramesOnGrid(crt_MOFrames - 1);
                        DrawPanelFrame();
                    }
                }
            }
        }

        //Down Module Of Frames button click
        public void downModuleOfFrame()
        {
            if (spr != null && spr.lst_Frames != null && spr.lst_Frames.Count > 0
                && dataGridView_Frames.CurrentRow != null
                && dataGridView_Frames.Rows.Count > 0)
            {
                int crt_FrameIndex = dataGridView_Frames.CurrentRow.Index;
                if (spr.lst_Frames[crt_FrameIndex].lst_ModulesOfFrame != null
                    && spr.lst_Frames[crt_FrameIndex].lst_ModulesOfFrame.Count >= 2
                    && dataGridView_ModulesOfFrame.CurrentRow != null
                    && dataGridView_ModulesOfFrame.Rows.Count >= 2)
                {
                    int crt_MOFrames = dataGridView_ModulesOfFrame.CurrentRow.Index;
                    if (crt_MOFrames < dataGridView_ModulesOfFrame.Rows.Count - 1)
                    {
                        spr.downModuleOfFramesAtIndex(crt_FrameIndex, crt_MOFrames);

                        refreshModuleOfFramesGrid();
                        setCurrentModuleOfFramesOnGrid(crt_MOFrames + 1);
                        DrawPanelFrame();
                    }
                }
            }
        }

        //Draw Frame Panel
        private void DrawPanelFrame()
        {
            if (bufferBitmap == null || panel_Frames.Width != bufferBitmap.Width || panel_Frames.Height != bufferBitmap.Height)
            {
                if (panel_Frames.Width > 0 && panel_Frames.Height > 0)
                    bufferBitmap = new Bitmap(panel_Frames.Width, panel_Frames.Height);
            }
            Graphics g_main = panel_Frames.CreateGraphics();
            Graphics g = Graphics.FromImage(bufferBitmap);
            g.Clear(panel_Frames.BackColor);

            //panel_Frames.Controls.Clear();

            if (spr != null && spr.spr_image != null)
            {
                Pen root_pen = new Pen(Color.Brown, 2);
                g.DrawLine(root_pen, new Point(0, root_Frames_Grid_Pos.Y), new Point(panel_Frames.Width, root_Frames_Grid_Pos.Y));
                g.DrawLine(root_pen, new Point(root_Frames_Grid_Pos.X, 0), new Point(root_Frames_Grid_Pos.X, panel_Frames.Height));

                if (spr.lst_Modules != null)
                {
                    if (spr.lst_Frames != null
                        && spr.lst_Frames.Count > 0
                        && dataGridView_Frames.CurrentRow.Index < spr.lst_Frames.Count
                        && spr.lst_Frames[dataGridView_Frames.CurrentRow.Index].lst_ModulesOfFrame != null)
                    {
                        List<ModulesOfFrame> tmp_mof = spr.lst_Frames[dataGridView_Frames.CurrentRow.Index].lst_ModulesOfFrame;

                        for (int i = 0; i < spr.lst_Frames[dataGridView_Frames.CurrentRow.Index].lst_ModulesOfFrame.Count; i++)
                        //for (int i = spr.lst_Frames[dataGridView_Frames.CurrentRow.Index].lst_ModulesOfFrame.Count - 1; i >= 0 ; i--)
                        {
                            Module tmp_Module = spr.getModuleFromID(tmp_mof[i].ID);
                            if (tmp_Module == null || tmp_Module.img == null)
                            {
                                g.DrawString("Invalid Module", new Font(new FontFamily("Arial"), 12), new SolidBrush(Color.Red), new Point(10, 10));
                            }
                            else
                            {
                                Point tmp_module_pos = SpriteCalculation.ConvertToRoot(new Point(tmp_mof[i].OX, tmp_mof[i].OY), root_Frames_Grid_Pos);

                                //OwnPanel modules_panel = new OwnPanel() { Width = tmp_Module.W, Height = tmp_Module.H };
                                //modules_panel.BackgroundImage = tmp_Module.img;
                                //modules_panel.Location = tmp_module_pos;
                                //modules_panel.CurrentIndex = i;
                                //modules_panel.MouseClick += new MouseEventHandler(modules_panel_MouseClick);
                                //modules_panel.MouseMove += new MouseEventHandler(modules_panel_MouseMove);
                                //modules_panel.MouseDown += new MouseEventHandler(modules_panel_MouseDown);
                                //modules_panel.MouseUp += new MouseEventHandler(modules_panel_MouseUp);

                                //modules_panel.ContextMenuStrip = contextMenuStripModule;

                                //panel_Frames.Controls.Add(modules_panel);

                                bool isFlipHorizontally = tmp_mof[i].isFlipHorizontally();
                                bool flipVertically = tmp_mof[i].isFlipVertically();

                                g.DrawImage(SpriteCalculation.FlipBitmap(tmp_Module.img, isFlipHorizontally, flipVertically), tmp_module_pos);
                            }
                        }
                    }
                }

                if (frames_editor_mode == PANEL_EDIT_RECT_MODE && CurSel_Frame != null)
                {
                    Pen rect_pen = new Pen(Color.Blue);
                    g.DrawRectangle(rect_pen, SpriteCalculation.ConvertToRoot(new Rectangle(CurSel_Frame.P1.X, CurSel_Frame.P1.Y, CurSel_Frame.P2.X - CurSel_Frame.P1.X, CurSel_Frame.P2.Y - CurSel_Frame.P1.Y), root_Frames_Grid_Pos));
                }
            }
            g_main.DrawImage(bufferBitmap, 0, 0);
        }

        private void DrawFlowPanelFrame()
        {
            //Graphics g = flowLayoutPanel_Frame.CreateGraphics();
            //g.Clear(flowLayoutPanel_Frame.BackColor);

            flowLayoutPanel_Frame.Controls.Clear();

            if (spr != null && spr.spr_image != null && spr.lst_Modules != null)
            {
                for (int i = 0; i < spr.lst_Modules.Count; i++)
                {
                    OwnPanel modules_flow_panel = new OwnPanel() { Width = 94, Height = 94 };
                    modules_flow_panel.BorderStyle = BorderStyle.Fixed3D;

                    if (spr.lst_Modules[i].img != null)
                    {
                        int f_tile = SpriteCalculation.Min(92000 / spr.lst_Modules[i].img.Width, 92000 / spr.lst_Modules[i].img.Height);

                        Bitmap small_bitmap = new Bitmap(spr.lst_Modules[i].img, spr.lst_Modules[i].img.Width * f_tile / 1000, spr.lst_Modules[i].img.Height * f_tile / 1000);

                        modules_flow_panel.BackgroundImage = small_bitmap;
                    }
                    else
                    {
                        modules_flow_panel.BackColor = EMPTY_CONTROL_COLOR;
                    }

                    modules_flow_panel.BackgroundImageLayout = ImageLayout.Center;
                    if (i == curModuleIndexInFrameFlow)
                        modules_flow_panel.BackColor = CURRENT_SELECTION_COLOR;
                    //else
                    //    modules_flow_panel.BackColor = Color.LightGray;

                    modules_flow_panel.CurrentIndex = i;
                    modules_flow_panel.MouseDoubleClick += new MouseEventHandler(modules_flow_panel_MouseDoubleClick);
                    modules_flow_panel.MouseClick += new MouseEventHandler(modules_flow_panel_MouseClick);
                    flowLayoutPanel_Frame.Controls.Add(modules_flow_panel);

                    //Graphics g = modules_flow_panel.CreateGraphics();

                    //g.DrawImage(small_bitmap, new Point(i * MODULE_BITMAP_WIDTH + 2 + (96 - small_bitmap.Width) / 2, 2 + (96 - small_bitmap.Height) / 2));
                    //g.DrawImage(small_bitmap, new Point((96 - small_bitmap.Width) / 2, (96 - small_bitmap.Height) / 2));
                }
            }
        }

        public void updateFlowPanelFrameSelection(int curMOFSelection)
        {
            if (flowLayoutPanel_Frame.Controls != null
                && flowLayoutPanel_Frame.Controls.Count > 0
                && curMOFSelection >= 0
                && flowLayoutPanel_Frame.Controls.Count > curMOFSelection)
            {
                curModuleIndexInFrameFlow = curMOFSelection;
                for (int i = 0; i < flowLayoutPanel_Frame.Controls.Count; i++)
                {
                    if (i == curModuleIndexInFrameFlow)
                        flowLayoutPanel_Frame.Controls[i].BackColor = CURRENT_SELECTION_COLOR;
                    else
                        flowLayoutPanel_Frame.Controls[i].BackColor = Color.LightGray;
                }
                //flowLayoutPanel_Frame.Refresh();
            }
        }
    }
}